package com.hjy.cabinet.ws.service;

import android.util.Log;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hjy.cabinet.ws.domain.ws.InfoBackEvent;
import com.hjy.cabinet.ws.domain.ws.WbsocketResponseBody;
import com.hjy.cabinet.ws.domain.ws.WebSocketRequest;
import com.hjy.cabinet.ws.domain.ws.WsData;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class WebsocketService {
    private Map<String, InfoBackEvent> infoMap = new HashMap<>();
    private static final Random random = new Random();

    private static WebsocketService instance;

    private WebsocketService() {
    }


    public static WebsocketService getInstance() {
        if (instance == null) {
            synchronized (WebsocketService.class) {
                if (instance == null) {
                    instance = new WebsocketService();
                }
            }
        }
        return instance;
    }

    public WbsocketResponseBody sendMessageSynchronous(WebSocketRequest webSocketRequest) {
        Log.d("NET", "sendMessageSynchronous1"+"-"+webSocketRequest.getMethodName());

        //默认超时时间是5秒
        int timeOut = 5 * 100;
        final WbsocketResponseBody[] body = {new WbsocketResponseBody()};
        final Boolean[] result = {false};
        //创建返回对象
        InfoBackEvent infoBackEvent = info -> {
            result[0] = true;
            body[0] = info;
        };

        //判断当前有没有客户端连接
        String connId = generateUniqueId();
        webSocketRequest.setConnId(connId);
        String request = dealWebSocketRequest(webSocketRequest);
        String requestResult = sendMessageSToService("send-" + request);
        if (requestResult != null) {

            WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
            wbsocketResponseBody.setStatus("fail");
            wbsocketResponseBody.setMsg(requestResult);
            return wbsocketResponseBody;
        }
        infoMap.put(connId, infoBackEvent);
        while (true) {
            if (result[0]) {
                break;
            }
            try {
                Thread.sleep(10);
                timeOut = timeOut - 1;
                if (timeOut == 0) {
                    WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
                    wbsocketResponseBody.setMethodName(webSocketRequest.getMethodName());
                    wbsocketResponseBody.setStatus("fail");
                    wbsocketResponseBody.setMsg("请求超时");
                    Log.d("NET", "请求超时1");

                    infoMap.remove(connId);
                    return wbsocketResponseBody;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        return body[0];


    }

    public WbsocketResponseBody sendMessageSynchronous(WebSocketRequest webSocketRequest, int timeOut) {
        for (Object arg : webSocketRequest.getArgs()) {
            Log.d("NET", "sendMessageSynchronous"+"-"+webSocketRequest.getMethodName()+"-"+arg);
        }



        //默认超时时间是5秒
        timeOut = timeOut * 100;
        final WbsocketResponseBody[] body = {new WbsocketResponseBody()};
        final Boolean[] result = {false};
        //创建返回对象
        InfoBackEvent infoBackEvent = info -> {
            result[0] = true;
            body[0] = info;
        };

        //判断当前有没有客户端连接
        String connId = generateUniqueId();
        webSocketRequest.setConnId(connId);
        String request = dealWebSocketRequest(webSocketRequest);
        String requestResult = sendMessageSToService("send-" + request);
        if (requestResult != null) {

            WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
            wbsocketResponseBody.setStatus("fail");
            wbsocketResponseBody.setMsg(requestResult);
            return wbsocketResponseBody;
        }
        infoMap.put(connId, infoBackEvent);

        while (true) {
            if (result[0]) {
                break;
            }
            try {
                Thread.sleep(10);
                timeOut = timeOut - 1;
                if (timeOut == 0) {
                    Log.d("NET", "请求超时");
                    WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
                    wbsocketResponseBody.setStatus("fail");
                    wbsocketResponseBody.setMsg("请求超时");
                    infoMap.remove(connId);
                    return wbsocketResponseBody;
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        Log.d("testfeng", "正常请求");
        return body[0];


    }


    public void sendMessageAsynchronous(WebSocketRequest webSocketRequest) {
        String requestString = null;
        try {
            requestString = dealWebSocketRequest(webSocketRequest);
            sendMessageAToService("send-" + requestString);
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }
    }


    //发消息去服务端 同步
    private String sendMessageSToService(String message) {
        if (!WsData.getKa()) {
            NetworkHander networkHander = NetworkHander.getInstance();
            networkHander.reConnect(5);
        }
        if (WsData.webSocket != null) {
            WsData.webSocket.send(message);
            return null;
        } else {
            return "网络无法连接";
        }
    }


    //发消息去服务端 异步
    private void sendMessageAToService(String message) {
        if (!WsData.getKa()) {
            new Thread(() -> {
                NetworkHander networkHander = NetworkHander.getInstance();
                networkHander.reConnect(5);
            }).start();
        }
        WsData.webSocket.send(message);
    }

    public void backMessage(WbsocketResponseBody wbsocketResponseBody) {
        String requestString = null;
        try {
            requestString = dealWebSocketWbsocketResponseBody(wbsocketResponseBody);
            sendMessageAToService("receive-" + requestString);
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        }
    }

    private static String generateUniqueId() {
        long timestamp = System.currentTimeMillis();
        int randomNum = random.nextInt(1000); // 生成 0 到 999 的随机数
        return String.valueOf(timestamp + randomNum);
    }

    private String dealWebSocketRequest(WebSocketRequest webSocketRequest) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            Object[] args = webSocketRequest.getArgs();
            Object[] newArgs = new Object[args.length];
            for (int i = 0; i < args.length; i++) {
                Object arg = args[i];
                newArgs[i] = mapper.writeValueAsString(arg);

                webSocketRequest.setArgs(newArgs);
            }
            String request = mapper.writeValueAsString(webSocketRequest);
            return request;
        } catch (JsonProcessingException e) {
            throw new RuntimeException("参数请求异常");
        }
    }


    private String dealWebSocketWbsocketResponseBody(WbsocketResponseBody wbsocketResponseBody) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            String responseBody = mapper.writeValueAsString(wbsocketResponseBody);
            return responseBody;
        } catch (JsonProcessingException e) {
            throw new RuntimeException("参数请求异常");

        }
    }

    public Map<String, InfoBackEvent> getInfoMap() {
        return infoMap;
    }

    public void setInfoMap(Map<String, InfoBackEvent> infoMap) {
        this.infoMap = infoMap;
    }
}
